


import {beginWork} from './ReactFiberBeginWork';
import {Update, Passive, NoFlags } from './ReactFiberFlags';
import { FunctionComponent } from './ReactWorkTags';
import { commitLifeCycles as commitLayoutEffectOnFiber } from './ReactFiberCommitWork';
import { HasEffect as HookHasEffect, Layout as HookLayout } from './ReactHookEffectTags';

let finishedWork = null
let workInProgress = null;
let pendingPassiveHookEffectsMount = [];
let pendingPassiveHookEffectsUnmount = [];


// useEffect的fiber.tag = 1000000100     effect.tag = 101
// useLayoutEffect的fiber.tag = 0000000100     effect.tag = 011


//每一个fiber都是一个工作单元
function performUnitOfWork(unitOfWork){
    let current = unitOfWork.alternate;//更新的时候就有current
    return beginWork(current,unitOfWork);
}
function workLoop(){
    //每个fiber是一个工作单元，每完成一个fiber,会看看有没有剩余时间，如果有接着干下一个，如果没有就
    //退出循环
    while (workInProgress) {
        workInProgress = performUnitOfWork(workInProgress);
    }
    // debugger
    commitRoot();
}

function commitRoot() {
    if (!finishedWork) return;
    commitBeforeMutationEffects();
    // debugger
    commitMutationEffects();
    commitLayoutEffects();
}

export function enqueuePendingPassiveHookEffectMount(fiber, effect,) {
    pendingPassiveHookEffectsMount.push(effect, fiber);
}

export function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {
    pendingPassiveHookEffectsUnmount.push(effect, fiber);
}





function commitLayoutEffects() {
    const flags = finishedWork.flags;
    if (flags & Update) { 
        const current = finishedWork.alternate;
        commitLayoutEffectOnFiber(finishedWork, current, finishedWork);
    }
}
function commitMutationEffects() {
    const flags = finishedWork.flags;
    const primaryFlags = flags & (Update);
    switch (primaryFlags) {
        case Update: {
            const current = finishedWork.alternate;
            commitWork(current, finishedWork);
            break;
        }
        default:
            break;
    }
}
function commitWork(current, finishedWork) {
    switch (finishedWork.tag) {
        case FunctionComponent:
            commitHookEffectListUnmount(
                HookLayout | HookHasEffect,
                finishedWork
            );
            break;
        default:
            break;
    }
}
function commitHookEffectListUnmount(tag, finishedWork) {
    const updateQueue = finishedWork.updateQueue;
    const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
    if (lastEffect !== null) {
        const firstEffect = lastEffect.next;
        let effect = firstEffect;
        do {
            if ((effect.tag & tag) === tag) {
                const destroy = effect.destroy;
                effect.destroy = undefined;
                if (destroy !== undefined) {
                    destroy();
                }
            }
            effect = effect.next;
        } while (effect !== firstEffect);
    }
}
// 
function commitBeforeMutationEffects() {
    const flags = finishedWork.flags;
    if ((flags & Passive) !== NoFlags) {
        setTimeout(flushPassiveEffects);
    }
}


function flushPassiveEffects() {
    debugger
    const unmountEffects = pendingPassiveHookEffectsUnmount;
console.log('unmountEffects: ',unmountEffects);
    pendingPassiveHookEffectsUnmount = [];
    for (let i = 0; i < unmountEffects.length; i += 2) {
        const effect = unmountEffects[i];
        const destroy = effect.destroy;
        effect.destroy = undefined;
        if (typeof destroy === 'function') {
            destroy();
        }
    }
    const mountEffects = pendingPassiveHookEffectsMount;
    pendingPassiveHookEffectsMount = [];
    for (let i = 0; i < mountEffects.length; i += 2) {
        const effect = mountEffects[i]
        const create = effect.create;
        effect.destroy = create();
    }
}

/**
 * 我们是讲hooks.所以简化一些逻辑
 * 在源码里此处要从当前fiber,向找到根节点再进行更新
 * 老的counterFiber向上找到根节点fiberRoot->然后再一级一级向下执行render再次渲染CounterFiber
 * @param {} fiber 
 */
export function scheduleUpdateOnFiber(oldFiber){//current Fiber
    let newFiber = {
        ...oldFiber,
        alternate:oldFiber
    }//新的CounterFiber开始执行更新
    finishedWork = workInProgress = newFiber;
    workLoop();
}
//正常来说我们需要根节点一下向下构建，Counter

export function render(fiber){
    // debugger
    finishedWork = workInProgress = fiber;
    workLoop();
}